﻿using Max.PH5_2004A.Shopping.DAL;
using Max.PH5_2004A.Shopping.Domain;
using Max.PH5_2004A.Shopping.DTO;
using Max.PH5_2004A.Shopping.DTO.Goods;
using Max.PH5_2004A.Shopping.IService;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Max.PH5_2004A.Shopping.API.Controllers
{
    [Route("goods")]
    [ApiController]
    public class GoodsController : ControllerBase
    {

        MaxPH52004AShoppingDbContext _context;

        IGoodsService _service;
        IGoodsImgService _goodsImgService;
        CSRedis.CSRedisClient redis = null;
        public GoodsController(IGoodsService service, IGoodsImgService goodsImgService, MaxPH52004AShoppingDbContext context)
        {
            _service = service;
            _goodsImgService = goodsImgService;

            _context = context;


            //我们的购物车是redis
            //第一步：连接到redis服务器
            redis = new CSRedis.CSRedisClient("127.0.0.1:6379");
            RedisHelper.Initialization(redis);
        }

        #region 商品相关


        [HttpGet("select")]
        public IActionResult Select(string? name,string? sortField="id",string? sortValue="asc", int pageIndex = 1, int pageSize = 10)
        {
            ResponseResultDto dto = new();

            //获取所有数据
            var list = _service.Select();

            list = list.Where(x => x.Name.Contains(name ?? ""));

            var total = list.Count(); //查询后的结果的总记录数


            //排序
            if(sortField.ToLower().Equals("price"))
            {
                if(sortValue.ToLower().Equals("asc"))
                {
                    list =list.OrderBy(x => x.Price);
                }
            }



            list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize);

            var q = from a in list
                    select new
                    {
                        Name = a.Name,
                        Price = a.Price,
                        Id = a.Id,
                        Imgs = _goodsImgService.Select().Where(x => x.GoodsId == a.Id).ToList()
                    };
            dto.Data = new { total, q };

            return Ok(dto);
        }



        [HttpGet("fxsort")]
        public IActionResult FuXiSort(string? value,string? field,int pi=1,int ps=10)
        {

            var list = _service.Select(); //获取所有数据

            list = list.Skip((pi - 1) * ps).Take(ps); //分页

            field = field ?? ""; //排序（这个判断，是避免没传参数为null的情况）
            if(field =="price")
            {
                if(value == "asc")
                {
                    list = list.OrderBy(x => x.Price);
                }
                else
                {
                    list = list.OrderByDescending(x => x.Price);
                }
            }

            return Ok(list);
        }


        //添加测试商品
        [HttpPost("add")]
        public IActionResult AddTest(GoodsAndImgInputDto dto)
        {
            ResponseResultDto result = new();

            var r = _service.AddGoodsAndImg(dto);
            result.Data = r;


            return Ok(result);
        }


        //获取单个商品信息

        [HttpGet("single")]
        public IActionResult GetSingleGoods(string id)
        {
            ResponseResultDto result = new();

            var m =_service.Select(x => id.Equals(x.Id.ToString()));
            //_service.Select(x => x.Id == new Guid(id));

            var q = from a in m
                    select new
                    {
                        Name = a.Name,
                        Price = a.Price,
                        Id = a.Id,
                        Stock = a.Stock,
                        Desc = a.Description,
                        Imgs = _goodsImgService.Select().Where(x => x.GoodsId == a.Id).ToList()
                    };

            result.Data = q;

            return Ok(result);
        }



        #endregion


        #region 购物车

        //添加购物车
        [HttpPost("car/add")]
        public IActionResult AddCar(CarInfoDto B)
        {
            ResponseResultDto result = new();

            //具体的处理，你是要把它存放到数据表，还是redis，一会再说


            var key =  B.UserId; //表示在当前redis服务器中的唯一标识 （如用户ID，用户身份证号，手机号）

            //这样直接放到redis里面，永远是最新的一个商品
            //redis.Set(key, dto);

            //获取redis里面的商品
            List<CarInfoDto> A = redis.Get<List<CarInfoDto>>(key);

            //如果为空（则是第一次）
            if (A == null)
                A = new List<CarInfoDto>();



            //查出该商品的库存
            var number = _service.Select().Where(x => x.Id == B.GoodsId).FirstOrDefault()?.Sales;

            //添加相同的商品
            var m = A.Where(x => x.GoodsId == B.GoodsId).FirstOrDefault();
            if (m == null)
            {
                A.Add(B);
                //if (B.GoodsNumber <= number) { A.Add(B); }
                //else{
                //    result.Code = ResponseResultStatueCode.操作失败;
                //    result.Message = "库存不足";
                //    return Ok(result);
                //}
            }
            else
            {
                //同一商品（根据商品Id)，只需要数量相加即可
                m.GoodsNumber += B.GoodsNumber;

                //var n = m.GoodsNumber + B.GoodsNumber;
                //if (n <= number) //已加入购物车的数量和即将加入购物车的数量之和小于或等于库存数量，则可加入购物车
                //{

                //    //同一商品（根据商品Id)，只需要数量相加即可
                //    m.GoodsNumber += B.GoodsNumber;
                //}
                //else
                //{
                //    result.Code = ResponseResultStatueCode.操作失败;
                //    result.Message = "库存不足";
                //    return Ok(result);
                //}
            }

            redis.Set(key, A);

            return Ok(result);
        }


        //显示购物车
        [HttpGet("car/list")]
        public IActionResult GetCar(string? userid)
        {
            ResponseResultDto result = new();

            if(string.IsNullOrEmpty(userid))
            {
                result.Code = ResponseResultStatueCode.操作失败;
                result.Message = "参数无效";
                return Ok(result);
            }

            //处理数据
            var key = userid;

            if(!redis.Exists(key))
            {
                result.Code = ResponseResultStatueCode.操作失败;
                result.Message = "购物车为空";
                return Ok(result);
            }

            var list = redis.Get<List<CarInfoDto>>(key);

            var q = from a in list  //nosql 缓存里的数据
                    join b in _service.Select().ToList()  //sql 数据库里的数据
                    on a.GoodsId equals b.Id //根据商品id去查
                    //join c in _goodsImgService.Select().ToList() on a.GoodsId equals c.GoodsId
                    select new
                    {
                        //缓存里的字段（dto)
                        a.GoodsId,
                        a.UserId,
                        a.GoodsNumber,
                        a.GoodsPrice,
                        //还需要数据库里的图片、名称
                        b.Name,
                        Imgs = _goodsImgService.Select().Where(x=>x.GoodsId == b.Id)  //图片在图片表中，所以在关联查一次
                    };

            result.Data = q;

            return Ok(result);
        }

        //修改购买数量
        [HttpPut]
        public IActionResult UpdateCar(CarInfoDto dto)
        {

            ResponseResultDto result = new();

            //1、要修改数量，则需要先从缓存（redis）中，将数据拿出来
            var key = dto.UserId;
            var list = redis.Get<List<CarInfoDto>>(key);

            //2、然后去找到这个商品
            var m = list.Where(x => x.GoodsId == dto.GoodsId)?.FirstOrDefault();
            if(m != null) { 
             
                //同样，修改数据的时候，需要去判断库存


                m.GoodsNumber = dto.GoodsNumber;
            }
            //3、得新更新缓存
            redis.Set(key, list);

            return Ok(result);
        }

        //从购物车删除商品
        [HttpPost("car/delete")]
        public IActionResult Delete(CarInfoDto dto)
        {

            ResponseResultDto result = new();

            var key = dto.UserId;
            var list = redis.Get<List<CarInfoDto>>(key);

            var m =list.Where(x => x.GoodsId == dto.GoodsId)?.FirstOrDefault();

            if(m !=null)
            {
                list.Remove(m);
            }

            redis.Set(key, list);

            return Ok(result);
        }


        [HttpPost("car/delete/all")]
        public IActionResult DeleteALL(List<CarInfoDto> dtos)
        {
            ResponseResultDto result = new();

            var key = dtos[0].UserId;
            var list = redis.Get<List<CarInfoDto>>(key);

            var count = dtos.Count;
            for (int i = 0; i < count; i++)
            {
                var m = list.Where(x => x.GoodsId == dtos[i].GoodsId)?.FirstOrDefault();

                if (m != null)
                {
                    list.Remove(m);
                }
            }

            redis.Set(key, list);  //这里要注意一点：当这个集合里没有数据的时候，就删除这个key

            return Ok(result);
        }

        #endregion
    }

    public class CarInfoDto
    {
        public string UserId { get; set; }
        public Guid GoodsId { get; set; }
        public int GoodsNumber { get; set; }
        public decimal GoodsPrice { get; set; }
    }
}
